if ( !device_assigned(bus, devfn) )
break;
- reassign_device_ownership(d, dom0, bus, devfn);
+ deassign_device(d, bus, devfn);
gdprintk(XENLOG_INFO, "XEN_DOMCTL_deassign_device: bdf = %x:%x:%x\n",
bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
put_domain(d);
return hd->platform_ops->unmap_page(d, gfn);
}
+
+void deassign_device(struct domain *d, u8 bus, u8 devfn)
+{
+ struct hvm_iommu *hd = domain_hvm_iommu(d);
+
+ if ( !iommu_enabled || !hd->platform_ops)
+ return;
+
+ return hd->platform_ops->reassign_device(d, dom0, bus, devfn);
+}
release_domain_devices(d);
}
+void amd_iommu_return_device(struct domain *s, struct domain *t, u8 bus, u8 devfn)
+{
+ pdev_flr(bus, devfn);
+ reassign_device(s, t, bus, devfn);
+}
+
struct iommu_ops amd_iommu_ops = {
.init = amd_iommu_domain_init,
.assign_device = amd_iommu_assign_device,
.teardown = amd_iommu_domain_destroy,
.map_page = amd_iommu_map_page,
.unmap_page = amd_iommu_unmap_page,
+ .reassign_device = amd_iommu_return_device,
};
.teardown = iommu_domain_teardown,
.map_page = intel_iommu_map_page,
.unmap_page = intel_iommu_unmap_page,
+ .reassign_device = reassign_device_ownership,
};
/*
void iommu_domain_destroy(struct domain *d);
int device_assigned(u8 bus, u8 devfn);
int assign_device(struct domain *d, u8 bus, u8 devfn);
+void deassign_device(struct domain *d, u8 bus, u8 devfn);
void reassign_device_ownership(struct domain *source,
struct domain *target,
u8 bus, u8 devfn);
void (*teardown)(struct domain *d);
int (*map_page)(struct domain *d, unsigned long gfn, unsigned long mfn);
int (*unmap_page)(struct domain *d, unsigned long gfn);
+ void (*reassign_device)(struct domain *s, struct domain *t, u8 bus, u8 devfn);
};
#endif /* _IOMMU_H_ */